package br.com.puertorico.mecanismos.ui.tags;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

import javax.el.ELException;
import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.FaceletException;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;

/**
 * Tag respons&aacute;vel por descobrir o tipo de dados de um propriedade de um
 * entity (classe de entidade).
 *
 * @author <a href="mailto:daniel.camargo@ufms.br">Daniel Camargo</a>
 * @version 1.0
 */
public final class SetPropertyTypeHandler extends TagHandler {

	private final TagAttribute variable;

	private final TagAttribute valueBinding;

	public SetPropertyTypeHandler(final TagConfig config) {
		super(config);
		this.variable = this.getRequiredAttribute("variable");
		this.valueBinding = this.getRequiredAttribute("valueBinding");
	}

	@SuppressWarnings("rawtypes")
	public void apply(final FaceletContext faceletsContext,
			final UIComponent parent) throws IOException, FacesException,
			FaceletException, ELException {

		ValueExpression valueExpression = this.valueBinding.getValueExpression(
				faceletsContext, Object.class);

		String tvar = this.variable.getValue(faceletsContext);
		Class type = valueExpression.getType(faceletsContext);
		String ttype = "";
		if (type.isPrimitive()) {
			if ("char".equals(type.getName())) {
				ttype = "string";
			} else if ("boolean".equals(type.getName())) {
				ttype = "integer";
			} else if ("integer".equals(type.getName())
					|| "long".equals(type.getName())
					|| "short".equals(type.getName())) {
				ttype = "integer";
			} else if ("float".equals(type.getName())
					|| "double".equals(type.getName())) {
				ttype = "decimal";
			} else {
				ttype = "unknown";
			}
		} else {
			if (type == String.class || type == Character.class) {
				ttype = "string";
			} else if (type == Boolean.class) {
				ttype = "boolean";
			} else if (type == Date.class) {
				ttype = "date";
			} else if (type == BigInteger.class || type == Integer.class
					|| type == Long.class || type == Short.class) {
				ttype = "integer";
			} else if (type == BigDecimal.class || type == Float.class
					|| type == Double.class) {
				ttype = "decimal";
			} else {
				ttype = "unknown";
			}
		}
		faceletsContext.setAttribute(tvar, ttype);

		this.nextHandler.apply(faceletsContext, parent);
	}
}
